﻿
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Commnunications
{
    public class UdpSerialHandle : ChannelHandle
    {
        /// <summary>
        /// 串口构造函数
        /// </summary>
        /// <param name="serial"></param>
        public UdpSerialHandle(System.IO.Ports.SerialPort serial) : base(ChannelHandleType.Serial)
        {

        }
        /// <summary>
        /// udp构造函数
        /// </summary>
        /// <param name="socket"></param>
        public UdpSerialHandle(Socket socket) : base(ChannelHandleType.Udp)
        {
            this.dataStream = new byte[10240];
        }
        byte[] dataStream;
        //public void Open()
        //{
        //    if(Type == ChannelHandleType.Serial)
        //        Serial.Open();
        //}
        string _ip;
        Thread _thread;
        public void Start(string ip)
        {
            _ip = ip;
            _thread = new Thread(ReciveData);
            _thread.Start();
        }
        public void Stop()
        {
            _isStop = true;
        }
        /// <summary>
        /// 心跳,默认1000ms
        /// </summary>
        public int HeatInterval { get; set; } = 1000;
        public delegate void DataReceived(string ip, byte[] args, Exception error, bool isOffline);
        public event DataReceived OnDataReceived;
        private void ReciveData()
        {
            while (!_isStop)
            {
                Thread.Sleep(HeatInterval);
                if (!ChannelFactory.Ping(_ip))
                {
                    OnDataReceived(null, null, null, true);
                    continue;
                }
                try
                {
                    EndPoint clientPoint = new IPEndPoint(IPAddress.Any, 0);
                    int recv_len = this._socket.ReceiveFrom(this.dataStream, this.dataStream.Length, SocketFlags.None, ref clientPoint);
                    if (recv_len == 0)
                    {
                        Close();
                        return;
                    }
                    var receivedBytes = new byte[recv_len];
                    Array.Copy(dataStream, 0, receivedBytes, 0, recv_len);
                    if (OnDataReceived != null)
                        OnDataReceived(_socket.RemoteEndPoint.ToString(), receivedBytes, null, false);
                }
                catch (Exception e)
                {
                    if (OnDataReceived != null)
                        OnDataReceived(null, null, e, false);
                    //logger.Error(string.Format("{0}:{1}", _socket.LocalEndPoint, e.Message));
                }
            }
        }

        volatile bool _isStop = false;
        /// <summary>
        /// tcp
        /// </summary>
        public Socket Net
        {
            get => _socket;
            private set
            {
                _socket = value;
            }
        }
        Socket _socket;
        public override void Close()
        {
            if (Type == ChannelHandleType.Serial)
            {
                if (Serial != null)
                {
                    Serial.Close();
                    Serial = null;
                }
            }
            else
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
            }
        }
        #region serial begin
        //int _baudRate;
        //int _dataBits;
        //Parity _parity;
        //StopBits _stopBits;
        /// <summary>
        /// 串口对象
        /// </summary>
        public System.IO.Ports.SerialPort Serial { get; private set; }
        #endregion serial end
    }
}
